package com.qunar.mina.app.utils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.util.NumericUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.qunar.mina.app.config.AnalyzerConfig;
import com.qunar.mina.app.config.DirectoryConfig;
import com.qunar.wireless.ugc.qcfclient.dto.Address;
import com.qunar.wireless.ugc.qcfclient.dto.Album;
import com.qunar.wireless.ugc.qcfclient.dto.Auditor;
import com.qunar.wireless.ugc.qcfclient.dto.Record;
import com.qunar.wireless.ugc.qcfclient.dto.User;

public class WriterUtils {
    private static final Logger logger = LoggerFactory.getLogger(WriterUtils.class);
    private static IndexWriter fsAddressWriter;
    private static IndexWriter fsUserWriter;
    private static IndexWriter fsAuditorWriter;
    // private static IndexWriter fsPicWriter;
    private static IndexWriter fsRecWriter;
    private static IndexWriter fsAlbumWriter;
    static {
        try {
            fsAddressWriter = new IndexWriter(DirectoryConfig.getFsAddressDirectory(), AnalyzerConfig.getAnalyzer(),
                    MaxFieldLength.LIMITED);

            fsUserWriter = new IndexWriter(DirectoryConfig.getFSUserDirectory(), AnalyzerConfig.getAnalyzer(),
                    MaxFieldLength.LIMITED);

            fsAuditorWriter = new IndexWriter(DirectoryConfig.getFSAuditorDirectory(), AnalyzerConfig.getAnalyzer(),
                    MaxFieldLength.LIMITED);

            // fsPicWriter = new IndexWriter(DirectoryConfig.getFSPicDirectory(), AnalyzerConfig.getAnalyzer(),
            // MaxFieldLength.LIMITED);

            fsRecWriter = new IndexWriter(DirectoryConfig.getFSRecDirectory(), AnalyzerConfig.getAnalyzer(),
                    MaxFieldLength.LIMITED);

            fsAlbumWriter = new IndexWriter(DirectoryConfig.getFSAlbumDirectory(), AnalyzerConfig.getAnalyzer(),
                    MaxFieldLength.LIMITED);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        try {
            Runtime.getRuntime().addShutdownHook(new Thread() {
                @Override
                public void run() {
                    if (fsAddressWriter != null) {
                        try {
                            fsAddressWriter.close();
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }

                    if (fsUserWriter != null) {
                        try {
                            fsUserWriter.close();
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }

                    if (fsAuditorWriter != null) {
                        try {
                            fsAuditorWriter.close();
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }

                    if (fsRecWriter != null) {
                        try {
                            fsRecWriter.close();
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }

                    if (fsAlbumWriter != null) {
                        try {
                            fsAlbumWriter.close();
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }

                }
            });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static IndexWriter getFsAddressWriter() {
        return fsAddressWriter;
    }

    public static IndexWriter getUserWriter() {
        return fsUserWriter;
    }

    public static IndexWriter getAuditorWriter() {
        return fsAuditorWriter;
    }

    public static IndexWriter getRecWriter() {
        return fsRecWriter;
    }

    public static IndexWriter getAlbumcWriter() {
        return fsAlbumWriter;
    }

    public static IndexWriter getWriter(String writerName) {

        if (null == writerName || "".equalsIgnoreCase(writerName))
            return null;
        if (writerName.equals("address"))
            return getFsAddressWriter();
        if (writerName.equals("user"))
            return getUserWriter();
        if (writerName.equals("auditor"))
            return getAuditorWriter();
        if (writerName.equals("record"))
            return getRecWriter();
        if (writerName.equalsIgnoreCase("album"))
            return getAlbumcWriter();
        return null;
    }

    /**
     * 将address对象转换document
     */
    public static Document address2Document(Address address) {
        Document document = new Document();
        document.add(new Field("addressId", NumericUtils.longToPrefixCoded(address.getAddressId()), Store.YES,
                Index.NOT_ANALYZED));
        if (address.getName() != null && !"".equals(address.getName()))
            document.add(new Field("name", address.getName(), Store.YES, Index.ANALYZED));
        if (address.getDetail() != null && !"".equals(address.getDetail()))
            document.add(new Field("detail", address.getDetail(), Store.YES, Index.ANALYZED));
        if (address.getCityId() != null)
            document.add(new Field("cityId", address.getCityId().toString(), Store.YES, Index.NOT_ANALYZED));
        if (address.getProvinceId() != null)
            document.add(new Field("provinceId", address.getProvinceId().toString(), Store.YES, Index.NOT_ANALYZED));
        if (address.getRegionLevel() != null)
            document.add(new Field("regionLevel", address.getRegionLevel().toString(), Store.YES, Index.NOT_ANALYZED));
        if (address.getIsValid() != null)
            document.add(new Field("isValid", address.getIsValid().toString(), Store.YES, Index.NOT_ANALYZED));
        if (address.getIsDestination() != null)
            document.add(new Field("isDestination", address.getIsDestination().toString(), Store.YES,
                    Index.NOT_ANALYZED));
        if (address.getOpenType() != null)
            document.add(new Field("openType", address.getOpenType().toString(), Store.YES, Index.NOT_ANALYZED));
        if (address.getIsMunicipality() != null)
            document.add(new Field("isMunicipality", address.getIsMunicipality().toString(), Store.YES,
                    Index.NOT_ANALYZED));
        if (address.getCountryId() != null)
            document.add(new Field("countryId", address.getCountryId().toString(), Store.YES, Index.NOT_ANALYZED));
        if (address.getCountryName() != null && !address.getCountryName().equals(""))
            document.add(new Field("countryName", address.getCountryName(), Store.YES, Index.ANALYZED));
        if (address.getRecordType() != null)
            document.add(new Field("recordType", address.getRecordType().toString(), Store.YES, Index.NOT_ANALYZED));
        return document;
    }

    /**
     * 将user对象转换document
     */
    public static Document user2Document(User user) {
        Document document = new Document();
        document.add(new Field("userId", NumericUtils.longToPrefixCoded(user.getUserId()), Store.YES,
                Index.NOT_ANALYZED));
        if (user.getUsername() != null && !"".equals(user.getUsername()))
            document.add(new Field("username", user.getUsername(), Store.YES, Index.ANALYZED));
        if (user.getThirdNickName() != null && !"".equals(user.getThirdNickName()))
            document.add(new Field("thirdNickName", user.getThirdNickName(), Store.YES, Index.ANALYZED));

        return document;
    }

    /**
     * 将auditor对象转换为document
     * 
     * @param auditor
     * @return
     */
    public static Document auditor2Document(Auditor auditor) {
        Document document = new Document();
        document.add(new Field("auditorId", NumericUtils.intToPrefixCoded(auditor.getAuditorId()), Store.YES,
                Index.NOT_ANALYZED));
        if (auditor.getName() != null && !"".equals(auditor.getName()))
            document.add(new Field("name", auditor.getName(), Store.YES, Index.ANALYZED));

        if (auditor.getRtxAccount() != null && !"".equals(auditor.getRtxAccount()))
            document.add(new Field("rtxAccount", auditor.getRtxAccount(), Store.YES, Index.ANALYZED));

        return document;

    }

    /**
     * 将Record对象转换document
     * 
     * @param rec Record 对象
     * @return Document
     */
    public static Document rec2Document(Record rec) {

        Document document = new Document();
        document.add(new Field("id", NumericUtils.longToPrefixCoded(rec.getId()), Store.YES, Index.NOT_ANALYZED));
        // if (rec.getUserId() != 0) {
        // document.add(new Field("userId", NumericUtils.longToPrefixCoded(rec.getUserId()), Store.YES,
        // Index.NOT_ANALYZED));
        // }
        //
        // if (rec.getAuditorId() != 0) {
        // document.add(new Field("auditorId", NumericUtils.intToPrefixCoded(rec.getAuditorId()), Store.YES,
        // Index.NOT_ANALYZED));
        // }
        //
        // if (rec.getUrl() != null && !"".equals(rec.getUrl())) {
        // document.add(new Field("url", rec.getUrl(), Store.YES, Index.NOT_ANALYZED));
        // }
        //
        // if (rec.getDescription() != null && !"".equals(rec.getDescription())) {
        // document.add(new Field("description", rec.getDescription(), Store.YES, Index.ANALYZED));
        // }
        //
        // if (rec.getCreateTime() != null) {
        // document.add(new Field("createTime", DateTools.dateToString(rec.getCreateTime(), Resolution.SECOND),
        // Store.YES, Index.NOT_ANALYZED));
        // }
        //
        // if (rec.getAuditTime() != null) {
        // Date auditTime = rec.getAuditTime();
        // document.add(new Field("auditTime", DateTools.dateToString(auditTime, Resolution.SECOND), Store.YES,
        // Index.NOT_ANALYZED));
        // }

        if (rec.getActivityName() != null && !"".equals(rec.getActivityName())) {
            document.add(new Field("activityName", rec.getActivityName(), Store.YES, Index.ANALYZED));
        }

        // if (rec.getIllegalityStatus() != 0) {
        // document.add(new Field("illegalityStatus", String.valueOf(rec.getIllegalityStatus()), Store.YES,
        // Index.NOT_ANALYZED));
        // }
        // if (rec.getType() != 0) {
        // document.add(new Field("type", String.valueOf(rec.getType()), Store.YES, Index.NOT_ANALYZED));
        // }

        return document;
    }

    /**
     * album2doc
     */
    public static Document album2Document(Album a) {
        Document document = new Document();
        document.add(new Field("id", NumericUtils.longToPrefixCoded(a.getId()), Store.YES, Index.NOT_ANALYZED));

        if (a.getName() != null && !"".equals(a.getName())) {
            document.add(new Field("name", a.getName(), Store.YES, Index.ANALYZED));
        }

        return document;

    }

    public static Document object2Document(Object o) {

        if (o == null)
            return null;
        if (o instanceof Address) {
            Address addr = (Address) o;
            return address2Document(addr);
        }
        if (o instanceof Record) {
            Record rec = (Record) o;
            return rec2Document(rec);
        }
        if (o instanceof Auditor) {
            Auditor auditor = (Auditor) o;
            return auditor2Document(auditor);
        }
        if (o instanceof User) {
            User user = (User) o;
            return user2Document(user);
        }
        if (o instanceof Album) {
            Album a = (Album) o;
            return album2Document(a);
        }
        return null;
    }

    public static void addRecordDocs(IndexWriter fsIndexWriter) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "select id, activity_name from record where is_user_delete = 2";
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            long begin = System.currentTimeMillis();
            // 对record表建立索引
            while (rs.next()) {
                Record rec = new Record();
                rec.setId(rs.getLong("id"));
                // rec.setUserId(rs.getLong("user_id"));
                // rec.setUrl(rs.getString("url"));
                // rec.setDescription(rs.getString("description"));
                // rec.setAuditorId(rs.getInt("auditor_id"));
                // rec.setCreateTime(rs.getDate("create_time"));
                // rec.setAuditTime(rs.getDate("audit_time"));
                rec.setActivityName(rs.getString("activity_name"));
                // rec.setIllegalityStatus(rs.getInt("illegality_status"));
                // rec.setType(rs.getInt("type"));
                Document doc = WriterUtils.rec2Document(rec);
                fsIndexWriter.addDocument(doc);
            }
            fsIndexWriter.commit();
            long end = System.currentTimeMillis();
            logger.info("创建record索引库耗时:" + (end - begin) + "ms");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            JdbcUtils.release(conn, pstmt, rs);
        }
    }

    public static void addAuditorDocs(IndexWriter fsIndexWriter) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "select auditor_id, name, rtxAccount from auditor";
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            long begin = System.currentTimeMillis();
            // 对user表建立索引
            while (rs.next()) {
                Auditor auditor = new Auditor();
                auditor.setAuditorId(rs.getInt("auditor_id"));
                auditor.setName(rs.getString("name"));
                auditor.setRtxAccount(rs.getString("rtxAccount"));
                Document doc = WriterUtils.auditor2Document(auditor);
                fsIndexWriter.addDocument(doc);
            }
            fsIndexWriter.commit();
            long end = System.currentTimeMillis();
            logger.info("创建auditor索引库耗时:" + (end - begin) + "ms");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            JdbcUtils.release(conn, pstmt, rs);
        }
    }

    public static void addUserDocs(IndexWriter fsIndexWriter) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "select user_id, username, third_nick_name from user";
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            long begin = System.currentTimeMillis();
            // 对user表建立索引
            while (rs.next()) {
                User user = new User();
                user.setUserId(rs.getLong("user_id"));
                user.setUsername(rs.getString("username"));
                user.setThirdNickName(rs.getString("third_nick_name"));
                Document doc = WriterUtils.user2Document(user);
                fsIndexWriter.addDocument(doc);
            }
            fsIndexWriter.commit();
            long end = System.currentTimeMillis();
            logger.info("创建user索引库耗时:" + (end - begin) + "ms");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            JdbcUtils.release(conn, pstmt, rs);
        }
    }

    public static void addAddressDocs(IndexWriter fsIndexWriter) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "select address_id, name, detail, city_id, is_valid, is_destination, open_type, province_id, region_level, is_municipality, country_id, country_name, record_type from address";
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            long begin = System.currentTimeMillis();
            // 对address表建立索引
            while (rs.next()) {
                Address address = new Address();
                address.setAddressId(rs.getLong("address_id"));
                address.setName(rs.getString("name"));
                address.setDetail(rs.getString("detail"));
                address.setCityId(rs.getObject("city_id") == null ? null : rs.getInt("city_id"));
                address.setIsValid(rs.getInt("is_valid"));
                address.setIsDestination(rs.getInt("is_destination"));
                address.setOpenType(rs.getInt("open_type"));
                address.setProvinceId(rs.getObject("province_id") == null ? null : rs.getInt("province_id"));
                address.setRegionLevel(rs.getInt("region_level"));
                address.setIsMunicipality(rs.getInt("is_municipality"));
                address.setCountryId(rs.getObject("country_id") == null ? null : rs.getInt("country_id"));
                address.setCountryName(rs.getString("country_name"));
                address.setRecordType(rs.getInt("record_type"));
                Document doc = WriterUtils.address2Document(address);
                fsIndexWriter.addDocument(doc);
            }
            fsIndexWriter.commit();
            long end = System.currentTimeMillis();
            logger.info("创建address索引库耗时:" + (end - begin) + "ms");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            JdbcUtils.release(conn, pstmt, rs);
        }
    }

    public static void addAlbumDocs(IndexWriter fsIndexWriter) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "select id, name from album where is_user_delete = 2";
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            long begin = System.currentTimeMillis();
            // 对album表建立索引
            while (rs.next()) {
                Album a = new Album();
                a.setId(rs.getLong("id"));
                a.setName(rs.getString("name"));
                Document doc = WriterUtils.album2Document(a);
                fsIndexWriter.addDocument(doc);
            }
            fsIndexWriter.commit();
            long end = System.currentTimeMillis();
            logger.info("创建album索引库耗时:" + (end - begin) + "ms");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            JdbcUtils.release(conn, pstmt, rs);
        }
    }

}
